package sg.nus.iss.vmcs.dao;

import sg.nus.iss.vmcs.models.DrinksStore;
import sg.nus.iss.vmcs.utils.Environment;
import sg.nus.iss.vmcs.utils.StoreType;
import sg.nus.iss.vmcs.dao.DrinkPropertyLoader;
import sg.nus.iss.vmcs.dao.CashPropertyLoader;
import sg.nus.iss.vmcs.models.DrinksStoreItem;
import sg.nus.iss.vmcs.models.CashStoreItem;
import sg.nus.iss.vmcs.VMCSException;
import sg.nus.iss.vmcs.models.AbstractStoreFactory;
import sg.nus.iss.vmcs.models.CashStore;
import sg.nus.iss.vmcs.models.StoreObject;

/**
 * @author Seng Chia How
 *
 */
public class PropertyStoreDAO implements StoreDAO {

	private DrinkPropertyLoader dpp;
	private CashPropertyLoader cpp;
	
	/**
	 * Initializes a new copy of the PropertyStoreDAO
	 * @throws VMCSException When there is an error loading property files
	 */
	public PropertyStoreDAO() throws VMCSException {
		try {
			// get the property file paths from the environment property file;
	        dpp = new DrinkPropertyLoader(Environment.getInstance().getDrinkPropFile());
	        dpp.initialize();
	        cpp = new CashPropertyLoader(Environment.getInstance().getCashPropFile());
	        cpp.initialize();
	    } 
		catch (Exception e){
	          throw new VMCSException ("vmcs.dao.PropertyStoreDAO" , "Error loading Property Files: " + e);
	    }
	}
	
	/**
	 * Gets a drink store from the store factory and populates is with values from the property file
	 */
	public DrinksStore getDrinksStore() throws VMCSException {
		try {
			DrinksStore dStore = (DrinksStore) AbstractStoreFactory.getStoreFactory(StoreType.DRINKS).getStore();
			dStore.setStoreSize(dpp.getNumOfItems());
			
			for(int i = 0; i < dStore.getStoreSize(); i++) {
				DrinksStoreItem sItem = dpp.getItem(i + 1);
				StoreObject curObject = sItem.getContent();
				StoreObject existing  = dStore.findObject(curObject.getName());
				
				//Chances are item should not be existing
				if(existing == null) {
					dStore.addItem(i, sItem);
				}
				else {
					//If item exists and value is the same, can add to store
					if(curObject.getValue() == existing.getValue()) {
						dStore.addItem(i, sItem);
					}
					else {
						throw new VMCSException ("vmcs.dao.PropertyStoreDAO", "Duplicate brand with different price");
					}
				}
			}
						
			return dStore;
			
		} 
		catch (Exception e){
	          throw new VMCSException ("vmcs.dao.PropertyStoreDAO" , "Error getting drinks store: " + e);
		}
	}

	/**
	 * Saves drink store to the property file
	 * @param dStore Drink Store to save
	 */
	public void saveDrinksStore(DrinksStore dStore) throws VMCSException {
		try 
		{   	
			if (dStore != null) {
				dpp.setNumOfItems(dStore.getStoreSize());

				for(int i = 0; i < dpp.getNumOfItems(); i++){
					dpp.setItem(i, (DrinksStoreItem) dStore.getStoreItem(i));
				}

				dpp.saveProperty();
			}
		} 
		catch (Exception e){
			throw new VMCSException ("vmcs.dao.PropertyStoreDAO" , "Error saving to Drink Property File: " + e);
		}
	}

	/**
	 * Gets a Cash store from the store factory and populates is with values from the property file
	 */
	public CashStore getCashStore() throws VMCSException {
		try {
			//Get instance of drinks store
			CashStore cStore = (CashStore) AbstractStoreFactory.getStoreFactory(StoreType.CASH).getStore();
			cStore.setStoreSize(cpp.getNumOfItems());

	        for(int i = 0; i < cStore.getStoreSize(); i++) {
	        	cStore.addItem(i, cpp.getItem(i + 1));
	        }

	        return cStore;
	        
	    } 
		catch (Exception e){
	        throw new VMCSException ("vmcs.dao.PropertyStoreDAO" , "Error in initialize cash store " + e);
	    }
	}

	/**
	 * Saves Cash store to the property file
	 * @param cStore CashStore to save
	 */
	public void saveCashStore(CashStore cStore) throws VMCSException {
		try 
		{
			cpp.setNumOfItems(cStore.getStoreSize());

			for(int i = 0; i < cpp.getNumOfItems(); i++){
				cpp.setItem(i, (CashStoreItem) cStore.getStoreItem(i));
			}

			cpp.saveProperty();		
		} 
		catch (Exception e){
			throw new VMCSException ("vmcs.dao.PropertyStoreDAO" , "Error saving to Cash Property File: " + e);
		}
	}
}
